#include "Headers/UI/reservationeditdialog.h"
#include "ui_reservationeditdialog.h"

#include <QTextCodec>
#include <QMessageBox>

ReservationEditDialog::ReservationEditDialog(MyUtils::FormStatus formStatus, Reservation *reservation, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::ReservationEditDialog)
{
    ui->setupUi(this);

    this->setWindowFlags(Qt::Dialog |
                         Qt::WindowMinimizeButtonHint |
                         Qt::WindowMaximizeButtonHint);

    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));

    this->formStatus = formStatus;
    this->reservation = reservation;

    if (formStatus == MyUtils::Adding)
    {
        //ставим текущие даты
        ui->arrivalDateEdit->setDate(QDate::currentDate());
        ui->departureDateEdit->setDate(QDate::currentDate());
        client = NULL;
        room = NULL;
    }
    else if (formStatus == MyUtils::Editing)
    {
        //ставим даты
        ui->arrivalDateEdit->setDate(reservation->getArrivalDate());
        ui->departureDateEdit->setDate(reservation->getDepartureDate());

        //ставим клиента
        Client c = reservation->getClient();
        this->client = new Client(c.getId(), c.getFirstName(), c.getLastName(), c.getDocument(), c.getPhone());
        loadClient();

        //ставим комнату
        Room r = reservation->getRoom();
        this->room = new Room(r.getId(), r.getNumber(), r.getName(), r.getFloor(), r.getType());

        //ставим опции
        this->options = reservation->getOptions();

        countCost();
    }

    loadRoom();
    loadTypeOfRooms();
    loadAdvancedOptions();
    if (options.count() > 0)
        loadAddedAdvancedOptions();
}

ReservationEditDialog::~ReservationEditDialog()
{
    delete ui;
}

/**
  Вперед
  */
void ReservationEditDialog::on_nextPagePushButton_clicked()
{
    int currentPage = ui->stackedWidget->currentIndex();
    switch(currentPage)
    {
        case 1:
        {
            updateResult();
            ui->nextPagePushButton->setText(trUtf8("Завершить"));
            if (!check())
                ui->nextPagePushButton->setEnabled(false);
            break;
        }
        case 2:
        {
            finish();
            break;
        }
    }

    ui->previousPagePushButton->setEnabled(true);
    ui->stackedWidget->setCurrentIndex(ui->stackedWidget->currentIndex() + 1);

}

/**
  Назад
  */
void ReservationEditDialog::on_previousPagePushButton_clicked()
{
    ui->stackedWidget->setCurrentIndex(ui->stackedWidget->currentIndex() - 1);
    if (ui->stackedWidget->currentIndex() == 0)
        ui->previousPagePushButton->setEnabled(false);
    ui->nextPagePushButton->setEnabled(true);
    ui->nextPagePushButton->setText(trUtf8("Далее"));
}

/**
  Загрузить комбобокс типов номеров
  */
void ReservationEditDialog::loadTypeOfRooms()
{
    TypeOfRoomDataAccessor typeData;
    QSqlTableModel *model = typeData.getTypesOfRoom();
    ui->typeOfRoomComboBox->setModel(model);
    ui->typeOfRoomComboBox->setModelColumn(1);
    ui->typeOfRoomComboBox->insertItem(0, "");
    ui->typeOfRoomComboBox->setCurrentIndex(0);
}

/**
  Загрузить окно для работы с типами комнат
  */
void ReservationEditDialog::on_typeOfRoomBrowsePushButton_clicked()
{
    TypeOfRoomDialog typeDialog;
    typeDialog.exec();

    loadTypeOfRooms();
}

void ReservationEditDialog::loadClient()
{
    if (client)
    {
        ui->firstNameLineEdit->setText(client->getFirstName());
        ui->lastNameLineEdit->setText(client->getLastName());
        ui->documentLineEdit->setText(client->getDocument());
        ui->phoneLineEdit->setText(client->getPhone());
    }
}

/**
  Выбрать из старых клиентов
  */
void ReservationEditDialog::on_clientBrowsePushButton_clicked()
{
    ClientChooseDialog clientChooseDialog;
    clientChooseDialog.exec();
    client = clientChooseDialog.getCurrentClient();

    loadClient();
}

/**
  Выбрали тип комнаты
  */
void ReservationEditDialog::on_typeOfRoomComboBox_currentIndexChanged(int index)
{
}

/**
  Диалог доступных опций
  */
void ReservationEditDialog::on_optionBrowsePushButton_clicked()
{
    AdvanceOptionsDialog optionDialog;
    optionDialog.exec();

    loadAdvancedOptions();
}

void ReservationEditDialog::loadAdvancedOptions()
{
    AdvancedOptionDataAccessor optionData;
    QSqlTableModel *model = optionData.getAdvancedOptionsWithIgnored(options);

    ui->listView->setModel(model);
    ui->listView->setModelColumn(1);
}

void ReservationEditDialog::on_listView_activated(const QModelIndex &index)
{
    //TODO перенос дополнительных опций сюда
    ui->addOptionPushButton->setEnabled(true);
}

void ReservationEditDialog::updateResult()
{
    //клиент
    if (client)
    {
        ui->resultNameLabel->setText(ui->firstNameLineEdit->text());
        ui->resultLastNameLabel->setText(ui->lastNameLineEdit->text());
        ui->resultDocumentLabel->setText(ui->documentLineEdit->text());
        ui->resultPhoneLabel->setText(ui->phoneLineEdit->text());
    }

    //номер
    if (room)
    {
        ui->resultNumberLabel->setText(room->getNumber());
        ui->resultNameOfRoomLabel->setText(room->getName());
        ui->resultCostOfRoomNumber->setText(QString::number(room->getType().getCost()));
        ui->resultFloorLabel->setText(QString::number(room->getFloor()));
        ui->resultTypeOfRoomLabel->setText(room->getType().getName());
    }


    //дополнительные опции
    if (options.count() > 0)
    {
        AdvancedOptionDataAccessor dataOption;
        QSqlTableModel *addedModel = dataOption.getAdvancedOptionsWithConsisted(options);
        ui->resultOptionListWidget->setModel(addedModel);
        ui->resultOptionListWidget->setModelColumn(1);
    }
}

void ReservationEditDialog::finish()
{
    //клиент
    if (!client)
    {
        if (ui->firstNameLineEdit->text().isEmpty() ||
                ui->lastNameLineEdit->text().isEmpty() ||
                ui->documentLineEdit->text().isEmpty() ||
                ui->phoneLineEdit->text().isEmpty())
        {
            QMessageBox msg;
            msg.setText(trUtf8("Заполните пожалуйста все данные о клиенте\nВы можете сделать это на втором шаге"));
            msg.exec();
            return;
        }

        client = new Client(0,
                            ui->firstNameLineEdit->text(),
                            ui->lastNameLineEdit->text(),
                            ui->documentLineEdit->text(),
                            ui->phoneLineEdit->text());
        ClientDataAccessor clientData;
        clientData.setClient(*client);

        QSqlTableModel *clientModel = clientData.getClients();
        int client_id = clientModel->data(clientModel->index(clientModel->rowCount() - 1, 0)).toInt();
        client->setId(client_id);
        qDebug("Создали нового клиента с id = " + QString::number(client_id).toAscii());
    }

    if (room)
    {
        qDebug(QString::number(client->getId()).toAscii());
        Reservation reserv(0, *client, *room, ui->arrivalDateEdit->date(), ui->departureDateEdit->date(), false);
        reserv.setOptions(options);
        ReservationDataAccessor reservationData;
        if (formStatus == MyUtils::Adding)
            reservationData.setReservation(reserv);
        else if (formStatus == MyUtils::Editing)
        {
            reserv.setId(this->reservation->getId());
            reservationData.editReservation(reserv);
        }
    }
    else
    {
        QMessageBox msg;
        msg.setText(trUtf8("Выберите пожалуйста номер для проживания\nВы можете сделать это на первом шаге"));
        msg.exec();
        return;
    }
    this->close();
}

void ReservationEditDialog::on_firstNameLineEdit_editingFinished()
{
    nullClient();
}

void ReservationEditDialog::on_lastNameLineEdit_editingFinished()
{
    nullClient();
}

void ReservationEditDialog::nullClient()
{
    if (client)
    {
        delete client;
        client = NULL;
    }
}

void ReservationEditDialog::on_documentLineEdit_editingFinished()
{
    nullClient();
}

void ReservationEditDialog::on_phoneLineEdit_editingFinished()
{
    nullClient();
}

bool ReservationEditDialog::check()
{
    if (ui->resultNameLabel->text().isEmpty())
        return false;
    if (ui->resultLastNameLabel->text().isEmpty())
        return false;
    if (ui->resultDocumentLabel->text().isEmpty())
        return false;
    if (ui->resultPhoneLabel->text().isEmpty())
        return false;
    return true;
}

void ReservationEditDialog::loadRoom()
{
    RoomDataAccessor roomData;
    QSqlQueryModel * model = roomData.getRoomQueryModelWithFilter(
                ui->arrivalDateEdit->date(),
                ui->departureDateEdit->date(),
                ui->countSpinBox->value(),
                getCurrentTypeOfRoom());
    ui->roomTableView->setModel(model);
    ui->roomTableView->hideColumn(0);
    ui->roomTableView->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
}

/**
  Найти номер
  */
void ReservationEditDialog::on_searchRoomPushButton_clicked()
{
    loadRoom();
}

TypeOfRoom * ReservationEditDialog::getCurrentTypeOfRoom()
{
    int currentIndex = ui->typeOfRoomComboBox->currentIndex();
    int id_type = ui->typeOfRoomComboBox->model()->data(ui->typeOfRoomComboBox->model()->index(currentIndex, 0)).toInt();
    TypeOfRoomDataAccessor dataType;
    TypeOfRoom *typeOfRoom = dataType.getTypeOfRoom(id_type);
    return typeOfRoom;
}

void ReservationEditDialog::on_chooseRoomButton_clicked()
{
    if (ui->roomTableView->currentIndex().isValid())
        chooseRoom();
    else
    {
        QMessageBox msg;
        msg.setIcon(QMessageBox::Information);
        msg.setWindowTitle(trUtf8("Ошибка"));
        msg.setText(trUtf8("Пожалуйста выберите номер для того, чтобы добавить его"));
        msg.exec();
    }
}

Room * ReservationEditDialog::getCurrentRoom()
{
    int row = ui->roomTableView->currentIndex().row();
    QModelIndex index = ui->roomTableView->model()->index(row, 0);
    for(int i = 0; i < ui->roomTableView->model()->columnCount(); i++)
    {
        QModelIndex internalIndex = ui->roomTableView->model()->index(row, i);
        ui->roomTableView->model()->setData(internalIndex, Qt::red, Qt::BackgroundRole);
    }
    int id = ui->roomTableView->model()->data(index).toInt();
    RoomDataAccessor dataRoom;

    return dataRoom.getRoom(id);
}

void ReservationEditDialog::chooseRoom()
{
    room = getCurrentRoom();
    countCost();

}

int ReservationEditDialog::countDays()
{
    QDate first = ui->arrivalDateEdit->date();
    QDate second = ui->departureDateEdit->date();
    return first.daysTo(second);
}

void ReservationEditDialog::countCost()
{
    double cost = 0;
    if (room)
    {
        double roomCost = room->getType().getCost();
        cost = countDays() * roomCost;
    }

    ui->resultMoneyRoomLabel->setText(QString::number(cost));

    double optionsCost = 0;
    for(int i = 0; i < options.count(); i++)
    {
        optionsCost += options[i]->getCost();
    }

    ui->resultMoneyOptionLabel->setText(QString::number(optionsCost));

    cost += optionsCost;

    ui->resultMoneyItogoLabel->setText(QString::number(cost));

    ui->bottomCostLabel->setText(QString::number(cost));
}

void ReservationEditDialog::on_addOptionPushButton_clicked()
{
    if (ui->listView->currentIndex().isValid())
    {
        AdvancedOption *option = getCurrentAdvancedOption();
        options.push_back(option);
        loadAddedAdvancedOptions();
    }
    else
    {
        QMessageBox msg;
        msg.setIcon(QMessageBox::Information);
        msg.setWindowTitle(trUtf8("Ошибка"));
        msg.setText(trUtf8("Пожалуйста выберите опцию, чтобы добавить ее"));
        msg.exec();
    }
}

void ReservationEditDialog::loadAddedAdvancedOptions()
{
    AdvancedOptionDataAccessor dataOption;
    QSqlTableModel *addedModel = dataOption.getAdvancedOptionsWithConsisted(options);
    ui->optionListView->setModel(addedModel);
    ui->optionListView->setModelColumn(1);

    loadAdvancedOptions();

    countCost();
}

AdvancedOption * ReservationEditDialog::getCurrentAdvancedOption()
{
    int row = ui->listView->currentIndex().row();
    int id = ui->listView->model()->data(ui->listView->model()->index(row, 0)).toInt();
    AdvancedOptionDataAccessor dataOption;
    return dataOption.getAdvancedOption(id);
}

void ReservationEditDialog::on_listView_clicked(const QModelIndex &index)
{
    ui->addOptionPushButton->setEnabled(true);
}

/**
  Убрать доп.опцию
  */
void ReservationEditDialog::on_deleteOptionPushButton_clicked()
{
    if (ui->optionListView->currentIndex().isValid())
    {
        int row = ui->optionListView->currentIndex().row();
        int id = ui->optionListView->model()->data(ui->optionListView->model()->index(row, 0)).toInt();
        AdvancedOptionDataAccessor dataOption;
        AdvancedOption *option = dataOption.getAdvancedOption(id);
        for(int i = 0; i < options.count(); i++)
        {
            if (options[i]->getId() == option->getId())
            {
                options.removeAt(i);
                break;
            }
        }
        loadAddedAdvancedOptions();
    }
    else
    {
        QMessageBox msg;
        msg.setIcon(QMessageBox::Information);
        msg.setWindowTitle(trUtf8("Ошибка"));
        msg.setText(trUtf8("Пожалуйста выберите опцию, чтобы убрать ее"));
        msg.exec();
    }
}
